\author {Sven Goldt}
\title {The Linux Programmer's Guide}

\chapter {Sound Programming}
A PC has at least one sound device: the internal speaker.  But, you can
also buy a sound card to plug into your PC to provide a more
sophisticated sound device.  Look at the Linux Sound User's Guide or
the Sound-HOWTO for supported sound cards.

\section {Programming the internal speaker}
Believe it or not, your PC speaker is part of the Linux console and
thus a character device. Therefore, ioctl() requests exist to manipulate
it.  For the internal speaker the following 2 requests exist:

\begin {enumerate}
\item KDMKTONE

   \noindent Generates a beep for a specified time using the kernel timer.

   \noindent Example: {\tt ioctl (fd, KDMKTONE,(long) argument)}.

\item KIOCSOUND

   \noindent Generates an endless beep or stops a currently sounding beep.

   \noindent Example: {\tt ioctl(fd,KIOCSOUND,(int) tone)}.
\end {enumerate}

The {\tt argument} consists of the {\tt tone} value in the low word and
the duration in the high word. The {\tt tone} value is not the
frequency. The PC mainboard timer 8254 is clocked at 1.19 MHz and so 
it's 1190000/frequency. The duration is measured in timer ticks.  Both
ioctl calls return immediately so you can this way produce beeps
without blocking the program.\\ 
KDMKTONE should be used for warning signals because you don't have
to worry about stopping the tone.\\
KIOCSOUND can be used to play melodies as demonstrated in the example
program splay {\it (please send more .sng files to me).} To stop the
beep you have to use the {\tt tone} value 0.

\section {Programming a sound card}

For you as a programmer, it is important to know if the current Linux
system has a sound card plugged in. One way to check is to examine
/dev/sndstat.  If opening /dev/sndstat fails and errno=ENODEV then no
sound driver is activated which means you will get no help from the
kernel sound driver.  The same result might be achieved by trying to
open /dev/dsp as long as it is not a link to the pcsnd driver in which
case open() will not fail.

If you want to mess with a sound card at the hardware level you know
that some combination of outb() and inb() calls will detect the sound
card you are looking for.

By using the sound driver for your programs, chances are that they will
work on other i386 systems as well, since some clever people decided to
use the same driver for Linux, isc, FreeBSD and most other i386 based
systems.  It will aid in porting programs if Linux on other
architectures offers the same sound device interface.  A sound card is
not part of the Linux console, but is a special device. A sound card
mostly offers three main features:

\begin {samepage}
\begin {itemize}
\item Digital sample input/output
\item Frequency modulation output
\item A midi interface
\end {itemize}
\end {samepage}

Each of these features have their own device driver interface. For digital
samples it is /dev/dsp, for the frequency modulation it is
/dev/sequencer and for the midi interface it is /dev/midi.  The sound
settings (like volume, balance or bass) can be controlled via the
/dev/mixer interface.  For compatibility reasons a /dev/audio device
exists which can read SUN $\mu$-law sound data, but it maps to the
digital sample device.

You are right if you guessed that you use ioctl() to manipulate these
devices.  The ioctl() requests are defined in $<linux/soundcard.h>$ and
begin with SNDCTL\_.

\bigskip {\bf Since I don't own a soundcard
someone else has to continue here}

\endinput
